package com.rizzo.infrastructure.redis.serializer;

import com.google.gag.annotation.disclaimer.AhaMoment;
import com.google.gag.enumeration.Where;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.util.BitSet;

/**
 * {@link org.springframework.data.redis.serializer.RedisSerializer} for working with raw bits
 * represented by a {@link BitSet}.
 */
@AhaMoment(value = Where.TOILET)
public class BitmapSerializer implements RedisSerializer<BitSet> {

    @Override
    public byte[] serialize(BitSet bitSet) throws SerializationException {
        return toByteArrayReverse(bitSet);
    }

    @Override
    public BitSet deserialize(byte[] bytes) throws SerializationException {
        return fromByteArrayReverse(bytes);
    }

    public static BitSet fromByteArrayReverse(final byte[] bytes) {
        final BitSet bits = new BitSet();
        if (bytes != null) {
            for (int i = 0; i < bytes.length * 8; i++) {
                if ((bytes[i / 8] & (1 << (7 - (i % 8)))) != 0) {
                    bits.set(i);
                }
            }
        }
        return bits;
    }

    public static byte[] toByteArrayReverse(final BitSet bits) {
        byte[] bytes = null;
        if (bits != null) {
            bytes = new byte[bits.length() / 8 + 1];
            for (int i = 0; i < bits.length(); i++) {
                if (bits.get(i)) {
                    final int value = bytes[i / 8] | (1 << (7 - (i % 8)));
                    bytes[i / 8] = (byte) value;
                }
            }
        }
        return bytes;
    }
}
